/* discmacros.h for !DiscEx */



/* this describes the format of an Internal Disc Address - plus some flags */

typedef struct {
    unsigned sector:8;      /* 0 => unshared */
    unsigned fragid:15;
    Bool isdir:1;
    Bool islast:1;
    Bool haslink:1;
    unsigned spare:6;
} IDA;


/* the size in bytes of the number of words (part) occupied by a string s */
#define  WORD_SIZE(s)  (strlen(s)+4 & ~3)


/* useful macros for disc structures; in all cases, di is a DiscInfoPtr */

  /* returns a fragment's home zone number */
#define  HOME_ZONE(di, fragid)  ( ((fragid)==2) ? (di)->dr.nzones/2 : (fragid)/(di)->idsperzone )

  /* returns the address of the start of a zone in allocation units */
#define  ZONE_START(di, zone)  ( ((zone)==0) ? 0 : ((di)->zone0size+((zone)-1)*(di)->zonesize) )

  /* returns the number of sectors in n allocation units */
#define  SECS_IN_ALLOCS(di, n) ( ((di)->dr.log2bpmb>(di)->dr.log2secsize) ? ((n)<<((di)->dr.log2bpmb-(di)->dr.log2secsize)) : ((n)>>((di)->dr.log2secsize-(di)->dr.log2bpmb)) )

  /* returns the number of allocation units in n sectors */
#define  ALLOCS_IN_SECS(di, n) ( ((di)->dr.log2bpmb>(di)->dr.log2secsize) ? ((n)>>((di)->dr.log2bpmb-(di)->dr.log2secsize)) : ((n)<<((di)->dr.log2secsize-(di)->dr.log2bpmb)) )

  /* returns the zone number corresponding to an address in alloc units */
#define  ZONE_WITH(di, alloc) ( ((alloc)<(di)->zone0size) ? 0 : ((alloc)-(di)->zone0size)/(di)->zonesize+1 )

  /* returns the number of sectors needed to store n bytes */
#define  SECS_FOR(di, n) ( ((n)+(di)->secsize-1)>>(di)->dr.log2secsize )

  /* returns the number of sectors in the number of allocunits needed to
     store n sectors */
#define  UNSHARESIZE_FOR(di, s) ( ((s)+(di)->allocunit-1) & ~((di)->allocunit-1) )

  /* returns the number of sectors in the number of shareunits needed to
     store n sectors */
#define  SHARESIZE_FOR(di, s) ( ((s)+(di)->shareunit-1) & ~((di)->shareunit-1) )
